/*
 * @Author       : YeRuoyu
 * @Date         : 2023-06-01 14:40:15
 * @LastEditors  : YeRuoyu ruoyu722@qq.com
 * @LastEditTime : 2023-06-02 15:06:24
 * @FilePath     : \list.h
 * @Description  : 一个通用链表库
 * Copyright (c) 2023 by YeRuoyu ruoyu722@qq.com, All Rights Reserved.
 */

#ifndef _INC_LIST_H_
#define _INC_LIST_H_

#include <stdio.h>
typedef long BaseType_t;
typedef unsigned long UBaseType_t;

/* 是否使用container_of宏来获取指针节点 可以更省空间 */
#define USE_CONTAINER_OF_MACRO
/**
 * 获取某个成员变量所在的结构体指针
 * ptr 代表一个指向结构体中某个成员变量的指针；type 代表该结构体的类型；member 代表该成员变量的名称。
 */
#define container_of(ptr, type, member) \
	((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

struct xLIST;
struct xLIST_ITEM
{
	struct xLIST_ITEM *pxNext;	   /*< 指向链表中下一个 ListItem_t 的指针。Pointer to the next ListItem_t in the list. */
	struct xLIST_ITEM *pxPrevious; /*< 指向链表中上一个 ListItem_t 的指针。Pointer to the previous ListItem_t in the list. */
	void *pvContainer;			   /*< 指向包含列表项的对象的指针。Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */
	struct xLIST *pxList;		   /*< 指向放置此列表项的列表的指针(如果有的话)。Pointer to the list in which this list item is placed (if any). */
};
typedef struct xLIST_ITEM ListItem_t, *pListItem_t;

struct xMINI_LIST_ITEM
{
	struct xLIST_ITEM *pxNext;	   /*< 指向链表中下一个 ListItem_t 的指针。*/
	struct xLIST_ITEM *pxPrevious; /*< 指向链表中上一个 ListItem_t 的指针。*/
};
typedef struct xMINI_LIST_ITEM MiniListItem_t, *pMiniListItem_t;

struct xLIST
{
	UBaseType_t uxNumberOfItems; /*< 当前链表中有多少个节点。*/
	ListItem_t *pxIndex;		 /*< 用来遍历链表 Used to walk through the list.  Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
	MiniListItem_t xListEnd;	 /*< 包含最大可能项值的列表项，这意味着它始终位于列表的末尾，因此用作标记。List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
};
typedef struct xLIST List_t, *pList_t;

typedef void (*ListForEachCallBack_t)(ListItem_t *pxItem);

void vListInitialise(List_t *const pxList);
void vListInsertEnd(List_t *const pxList, ListItem_t *const pxNewListItem);
void vListForEach(const List_t *const pxList, ListForEachCallBack_t pCallBack);
UBaseType_t uxListRemove(ListItem_t *const pxItemToRemove);
UBaseType_t ulListLength(const List_t *const pxList);

#endif // _INC_LIST_H_
